package com.PTA.KeSheView;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import com.PTA.KeShe.Point;
import com.PTA.KeShe.Block;
import com.PTA.KeShe.VerifySuccess;

import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

/**
 * 事件监视器负责处理视图上触发的用户界面事件，以便完成相应的任务。
 *  HandleMove类是javax.swing包中JPanel容器的一个子类，并实现了MouseListener和ActionListener接口，
 *  创建的对象handleMove是魔板的重要成员之一。
 *  handleMove负责监视魔板中的方块上的鼠标事件。当用户用鼠标单击方块后，handleMove对象负责通知方块调用move（）方法。
 * 另外，监视器封装VerifuSuccess类的实例，以便让该实例判断用户是否成功地完成了游戏。HandleMove类还封装了javax。
 * swing。Timer计时器。
 * 构造方法Timer（int a，Object b）创建计时器。其中，a的单位是毫秒，确定计时器每隔a毫秒振铃一次，b是计时器的监视器。
 * 计时器发生的震玲事件是ActionEvent事件，当震铃发生时，监视器就会调用actionPerformed（ActionEvent）方法。
 * 当震铃每隔a毫秒发成一次，方法actionPerformed（ActionEvent）就会被调用。
 */

// 处理拼图移动的类，继承 JPanel 并实现 MouseListener 和 ActionListener 接口
public class HandleMove extends JPanel implements MouseListener, ActionListener {
    Point[][] Point;    // 魔板中的全部点，表示每个方块的位置
    int spendTime = 0;  // 记录用户的用时（秒）
    javax.swing.Timer recordTime; // 定时器，用于记录时间
    private JTextField showTime; // 显示用时的文本框
    VerifySuccess verify; // 验证拼图是否成功的工具类

    // 构造方法，初始化组件和布局
    HandleMove() {
        recordTime = new javax.swing.Timer(1000, this); // 定时器每秒触发一次
        showTime = new JTextField(16); // 创建一个不可编辑的文本框，长度为16
        showTime.setEditable(false); // 禁止手动输入
        showTime.setHorizontalAlignment(JTextField.CENTER); // 文本居中
        showTime.setFont(new Font("楷体_GB2312", Font.BOLD, 16)); // 设置字体

        JLabel hitMess = new JLabel("用鼠标单击方块", JLabel.CENTER); // 提示用户操作信息
        hitMess.setFont(new Font("楷体_GB2312", Font.BOLD, 18)); // 设置提示信息字体

        add(hitMess); // 添加提示信息到面板
        add(showTime); // 添加显示用时的文本框到面板
        setBackground(Color.cyan); // 设置背景颜色
    }

    // 设置魔板中的点数据
    public void setPoint(Point[][] p) {
        Point = p;
    }

    // 初始化用时记录
    public void initSpendTime() {
        recordTime.stop(); // 停止计时器
        spendTime = 0; // 重置用时
        showTime.setText(null); // 清空显示内容
    }

    // 设置验证拼图成功的工具类
    public void setVerifySuccess(VerifySuccess verify) {
        this.verify = verify;
    }

    // 鼠标按下事件，开始移动方块
    public void mousePressed(MouseEvent e) {
        recordTime.start(); // 开始计时
        Block block = null;
        block = (Block) e.getSource(); // 获取触发事件的方块
        Point startPoint = block.getAtPoint(); // 获取方块当前所在的位置
        int w = block.getBounds().width; // 获取方块的宽度
        int h = block.getBounds().height; // 获取方块的高度

        if (block.move()) { // 如果方块可以移动
            Point pEnd = block.getAtPoint();  // 获取方块移动后的新位置
            int x = pEnd.getX(); // 获取新位置的 x 坐标
            int y = pEnd.getY(); // 获取新位置的 y 坐标
            block.setLocation(x, y); // 设置方块的新位置
            block.setAtPoint(pEnd); // 更新方块的当前点信息
            pEnd.setBlock(block); // 在新位置设置方块
            pEnd.setHaveBlock(true); // 标记新位置有方块
            startPoint.setHaveBlock(false); // 标记原位置无方块
        }
    }

    // 定时器触发事件，用于更新用时
    public void actionPerformed(ActionEvent e) {
        spendTime++; // 用时加 1 秒
        showTime.setText("您的用时:" + spendTime + "秒"); // 更新文本框内容
    }

    // 鼠标释放事件，检查拼图是否完成
    public void mouseReleased(MouseEvent e) {
        if (verify.isSuccess()) { // 如果拼图完成
            recordTime.stop(); // 停止计时器
            JOptionPane.showMessageDialog(this, "恭喜你，您成功了！", "消息框", JOptionPane.INFORMATION_MESSAGE); // 弹出成功提示框
        }
    }

    // 空实现：鼠标进入事件
    public void mouseEntered(MouseEvent e) {}

    // 空实现：鼠标退出事件
    public void mouseExited(MouseEvent e) {}

    // 空实现：鼠标点击事件
    public void mouseClicked(MouseEvent e) {}
}
